#include "indicator.hpp"
#include "apm32a10x_gpio.h"
#include "apm32a10x_tmr.h"
#include "apm32a10x_rcm.h"
#include "system.h"
#include "stdio.h"

static GPIO_T *led_port = GPIOC;
static GPIO_PIN_T led_pin= GPIO_PIN_9;



class __LED : public LED {
public:
    virtual void set(bool status);
    virtual bool get();
};

void __LED::set(bool status){
    if ( status ){
        GPIO_ResetBit(led_port,led_pin);
    }else{
        GPIO_SetBit(led_port,led_pin);
    }
}

bool __LED::get(){
    if( GPIO_ReadInputBit(led_port,led_pin) ) return false;
    else return true;

}

static LED *led = nullptr;
LED *LED::getInstance(){
    if ( led == nullptr ){
        /* Initialize GPIO. */
        GPIO_Config_T gpio_configuration;
        System_setPeripheralClockEnable(CLK_GPIOC,TRUE);
        gpio_configuration.pin = led_pin;
        gpio_configuration.mode = GPIO_MODE_OUT_PP;
        gpio_configuration.speed = GPIO_SPEED_50MHz;
        GPIO_Config(led_port,&gpio_configuration);
        led = new __LED();
    }
    return led;
}


static GPIO_T *beeper_port = GPIOB;
static GPIO_PIN_T beeper_pin = GPIO_PIN_8;

class __Beeper : public Beeper {
public:
    virtual void set(bool status);
    virtual bool get();
    virtual bool setFrequency(unsigned int frequency);
    virtual unsigned int getFrequency();
    virtual void beeper_count(unsigned char count);
    virtual void beeper_time(unsigned char time);
private:
    bool flag=false;
};

void __Beeper::set(bool status){
    if( status == true ){
        TMR_Enable(TMR4);
        TMR_EnablePWMOutputs(TMR4);
        flag = true;
    }else{
        TMR_Disable(TMR4);
        TMR_DisablePWMOutputs(TMR4);
        flag = false;
    }
}

bool __Beeper::get(){
    return flag;
}

bool __Beeper::setFrequency(unsigned int frequency){

    TMR_ConfigCompare3(TMR4, 1000000/frequency);
}

unsigned int __Beeper::getFrequency(){
    // 获取定时器的ARR寄存器值
    return 0;
}

void __Beeper::beeper_count(unsigned char count){
    for(int i = 0; i < count * 2; i++)
    {
        this->set(!this->get());
        System_delayMs(500);
    }
}

void __Beeper::beeper_time(unsigned char time){
    this->set(true);
    for(int i = 0; i < time; i++)
    {
        System_delayMs(1000);
    }
    this->set(false);
}

static Beeper *beeper = nullptr;
Beeper *Beeper::getInstance(){
    if ( beeper == nullptr ){
        /* Initialize GPIO and TMR. */
        GPIO_Config_T gpio_configuration;
        TMR_BaseConfig_T tmr_configuration;
        TMR_OCConfig_T oc_configuration;
        RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOB);   
        RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR4);  
        gpio_configuration.pin = beeper_pin;
        gpio_configuration.mode = GPIO_MODE_AF_PP;
        gpio_configuration.speed = GPIO_SPEED_50MHz;
        GPIO_Config(beeper_port,&gpio_configuration);

        tmr_configuration.clockDivision = TMR_CLOCK_DIV_1;
        tmr_configuration.countMode = TMR_COUNTER_MODE_UP;
        tmr_configuration.division = 120;
        tmr_configuration.period = 999;      
        TMR_ConfigTimeBase(TMR4,&tmr_configuration);

        oc_configuration.idleState = TMR_OC_IDLE_STATE_RESET;
        oc_configuration.mode = TMR_OC_MODE_PWM1;
        oc_configuration.nIdleState = TMR_OC_NIDLE_STATE_RESET;
        oc_configuration.nPolarity = TMR_OC_NPOLARITY_HIGH;
        oc_configuration.outputNState = TMR_OC_NSTATE_ENABLE;
        oc_configuration.outputState = TMR_OC_STATE_ENABLE;
        oc_configuration.polarity = TMR_OC_POLARITY_HIGH;
        oc_configuration.pulse = 600;
        TMR_ConfigOC3(TMR4, &oc_configuration);
        
        TMR_ConfigOC3Preload(TMR4, TMR_OC_PRELOAD_ENABLE);
        TMR_EnableAutoReload(TMR4);
        TMR_Enable(TMR4);
        TMR_EnablePWMOutputs(TMR4);

        beeper = new __Beeper();
    }
    return beeper;
}



// /************************************** 有源蜂鸣器 ***************************************/
// #include "indicator.hpp"
// #include "apm32a10x_gpio.h"
// #include "apm32a10x_tmr.h"
// #include "apm32a10x_rcm.h"
// #include "system.h"
// #include "stdio.h"

// static GPIO_T *led_port = GPIOC;
// static GPIO_PIN_T led_pin= GPIO_PIN_9;



// class __LED : public LED {
// public:
//     virtual void set(bool status);
//     virtual bool get();
// };

// void __LED::set(bool status){
//     if ( status ){
//         GPIO_ResetBit(led_port,led_pin);
//     }else{
//         GPIO_SetBit(led_port,led_pin);
//     }
// }

// bool __LED::get(){
//     if( GPIO_ReadInputBit(led_port,led_pin) ) return false;
//     else return true;

// }

// static LED *led = nullptr;
// LED *LED::getInstance(){
//     if ( led == nullptr ){
//         /* Initialize GPIO. */
//         GPIO_Config_T gpio_configuration;
//         System_setPeripheralClockEnable(CLK_GPIOC,TRUE);
//         gpio_configuration.pin = led_pin;
//         gpio_configuration.mode = GPIO_MODE_OUT_PP;
//         gpio_configuration.speed = GPIO_SPEED_50MHz;
//         GPIO_Config(led_port,&gpio_configuration);
//         led = new __LED();
//     }
//     return led;
// }


// static GPIO_T *beeper_port = GPIOB;
// static GPIO_PIN_T beeper_pin = GPIO_PIN_8;

// class __Beeper : public Beeper {
// public:
//     virtual void set(bool status);
//     virtual bool get();
//     virtual bool setFrequency(unsigned int frequency);
//     virtual unsigned int getFrequency();
//     virtual void beeper_count(unsigned char count);
//     virtual void beeper_time(unsigned char time);
// private:
//     bool flag=false;
// };

// void __Beeper::set(bool status){
//     if( status == true ){
//         GPIO_SetBit(beeper_port,beeper_pin);
//         //TMR_EnablePWMOutputs(TMR4);
//         flag = true;
//     }else{
//         GPIO_ResetBit(beeper_port,beeper_pin);
//         //TMR_DisablePWMOutputs(TMR4);
//         flag = false;
//     }
// }

// bool __Beeper::get(){
//     return flag;
// }

// bool __Beeper::setFrequency(unsigned int frequency){

//     TMR_ConfigCompare3(TMR4, 1000000/frequency);
// }

// unsigned int __Beeper::getFrequency(){
//     unsigned int period = TMR4->CC3;
//     return 1000000/period;
// }

// void __Beeper::beeper_count(unsigned char count){
//     for(int i = 0; i < count * 2; i++)
//     {
//         this->set(!this->get());
//         System_delayMs(500);
//     }
// }

// void __Beeper::beeper_time(unsigned char time){
//     this->set(true);
//     for(int i = 0; i < time; i++)
//     {
//         System_delayMs(1000);
//     }
//     this->set(false);
// }

// static Beeper *beeper = nullptr;
// Beeper *Beeper::getInstance(){
//     if ( beeper == nullptr ){
//         /* Initialize GPIO and TMR. */
//         GPIO_Config_T gpio_configuration;
//         TMR_BaseConfig_T tmr_configuration;
//         TMR_OCConfig_T oc_configuration;
//         RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOB);   
//         gpio_configuration.pin = beeper_pin;
//         gpio_configuration.mode = GPIO_MODE_OUT_PP;
//         gpio_configuration.speed = GPIO_SPEED_50MHz;
//         GPIO_Config(beeper_port,&gpio_configuration);
//         beeper = new __Beeper();
//     }
//     return beeper;
// }

